%%% -*- mode: erlang -*-
-ifndef(rtps_psm_hrl).
-define(rtps_psm_hrl, true).

-define(RTPS_MSG_HEADER_SIZE, 20). 
-define(RTPS_SUBMSG_HEADER_SIZE, 4). 

%%==============================================================================
%% Communication related constants.
%% https://en.wikipedia.org/wiki/Maximum_transmission_unit#IP_MTUs_for_common_media
%%==============================================================================

-define(MTU_MIN, 576).
-define(MTU_DEFAULT, 1500). % 1464 if passing through a PPPoE connection
-define(MTU_MAX, 16#ffff). % 64K
-define(MTU, ?MTU_DEFAULT).

%% Integer limits
-define(SHORTMIN, -32768).
-define(SHORTMAX, 32767).
-define(USHORTMIN, 0).
-define(USHORTMAX, 65535).
-define(LONGMIN, -2147483648).
-define(LONGMAX, 2147483647).
-define(ULONGMIN, 0).
-define(ULONGMAX, 4294967295).
-define(LONGLONGMIN, -9223372036854775808).
-define(LONGLONGMAX, 9223372036854775807).
-define(ULONGLONGMIN, 0).
-define(ULONGLONGMAX, 18446744073709551615).

%% 8.3.3.1.3 vendorId
-define(VENDORID_UNKNOWN, <<0, 0>>).

%% 9.3.1.2 Mapping of the EntityId
-define(ENTITYID_UNKNOWN, <<0:32>>).
-define(ENTITY_TYPE_USER, 0).
-define(ENTITY_TYPE_BUILT_IN, 3).
-define(ENTITY_TYPE_VENDOR, 1).

-define(ENTITY_KIND_UNKNOWN, 0).
-define(ENTITY_KIND_PARTICIPANT, 1).
-define(ENTITY_KIND_WRITER_WITH_KEY, 2).
-define(ENTITY_KIND_WRITER_NO_KEY, 3).
-define(ENTITY_KIND_READER_NO_KEY, 4).
-define(ENTITY_KIND_READER_WITH_KEY, 7).

%% 9.3.2 Mapping of the Types that Appear Within Submessages or Built-in Topic Data
%% Time
-define(TIME_ZERO, 0).
-define(TIME_INVALID, 16#ffffffffffffffff).
-define(TIME_INFINITE, 16#7fffffffffffffff).
%% Locator
-define(LOCATOR_KIND_INVALID, -1).
-define(LOCATOR_ADDRESS_INVALID, 0).
-define(LOCATOR_PORT_INVALID, 0).
-define(LOCATOR_KIND_RESERVED, 0).
-define(LOCATOR_KIND_UDPv4, 1).
-define(LOCATOR_KIND_UDPv6, 2).

%% TopicKind
-define(NO_KEY, 1).
-define(WITH_KEY, 2).
%% ReliabilityKind
-define(BEST_EFFORT, 1).
-define(RELIABLE, 3).

%% Parameter list
%% Also see 9.6.2.2.2 ParameterID values
-define(PID_PAD, 0).
-define(PID_SENTINEL, 1).
-define(PID_USER_DATA, 16#2c).
-define(PID_TOPIC_NAME, 16#05).
-define(PID_TYPE_NAME, 16#07).
-define(PID_GROUP_DATA, 16#2d).
-define(PID_TOPIC_DATA, 16#2e).
-define(PID_DURABILITY, 16#1d).
-define(PID_DURABILITY_SERVICE, 16#1e).
-define(PID_DEADLINE, 16#23).
-define(PID_LATENCY_BUDGET, 16#27).
-define(PID_LIVELINESS, 16#1b).
-define(PID_RELIABILITY, 16#1a).
-define(PID_LIFESPAN, 16#2b).
-define(PID_DESTINATION_ORDER, 16#25).
-define(PID_HISTORY, 16#40).
-define(PID_RESOURCE_LIMITS, 16#41).
-define(PID_OWNERSHIP, 16#1f).
-define(PID_OWNERSHIP_STRENGTH, 16#06).
-define(PID_PRESENTATION, 16#21).
-define(PID_PARTITION, 16#29).
-define(PID_TIME_BASED_FILTER, 16#04).
-define(PID_TRANSPORT_PRIORITY, 16#49).
-define(PID_PROTOCOL_VERSION, 16#15).
-define(PID_VENDOR_ID, 16#16).
-define(PID_UNICAST_LOCATOR, 16#2f).
-define(PID_MULTICAST_LOCATOR, 16#30).
-define(PID_MULTICAST_IPADDRESS, 16#11).
-define(PID_DEFAULT_UNICAST_LOCATOR, 16#31).
-define(PID_DEFAULT_MULTICAST_LOCATOR, 16#48).
-define(PID_METATRAFFIC_UNICAST_LOCATOR, 16#32).
-define(PID_METATRAFFIC_MULTICAST_LOCATOR, 16#33).
-define(PID_DEFAULT_UNICAST_IPADDRESS, 16#0c).
-define(PID_DEFAULT_UNICAST_PORT, 16#0e).
-define(PID_METATRAFFIC_UNICAST_IPADDRESS, 16#45).
-define(PID_METATRAFFIC_UNICAST_PORT, 16#0d).
-define(PID_METATRAFFIC_MULTICAST_IPADDRESS, 16#0b).
-define(PID_METATRAFFIC_MULTICAST_PORT, 16#46).
-define(PID_EXPECTS_INLINE_QOS, 16#43).
-define(PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT, 16#34).
-define(PID_PARTICIPANT_BUILTIN_ENDPOINTS, 16#44).
-define(PID_PARTICIPANT_LEASE_DURATION, 16#02).
-define(PID_CONTENT_FILTER_PROPERTY, 16#35).
-define(PID_PARTICIPANT_GUID, 16#50).
-define(PID_PARTICIPANT_ENTITYID, 16#51).
-define(PID_GROUP_GUID, 16#52).
-define(PID_GROUP_ENTITYID, 16#53).
-define(PID_BUILTIN_ENDPOINT_SET, 16#58).
-define(PID_PROPERTY_LIST, 16#59).
-define(PID_TYPE_MAX_SIZE_SERIALIZED, 16#60).
-define(PID_ENTITY_NAME, 16#62).
-define(PID_KEY_HASH, 16#70).
-define(PID_STATUS_INFO, 16#71).
%% Table 9.14 - Inline QoS parameters
-define(PID_CONTENT_FILTER_INFO, 16#55).
-define(PID_COHERENT_SET, 16#56).
-define(PID_DIRECTED_WRITE, 16#57).
-define(PID_ORIGINAL_WRITER_INFO, 16#61).

%% Table 9.4 - BuiltinEndpointSet p158
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER, 16#1).
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR, 16#2).
-define(DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER, 16#4).
-define(DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR, 16#8).
-define(DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER, 16#10).
-define(DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR, 16#20).
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_ANNOUNCER, 16#40).
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_DETECTOR, 16#80).
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_ANNOUNCER, 16#100).
-define(DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_DETECTOR, 16#200).
-define(BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER, 16#400).
-define(BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER, 16#800).

%% 8.5.4.3 Built-in Endpoints required by the Simple Endpoint Discovery Protocol. 
-define(BuiltinEndpointSet,
	[
	 %% {participant_writer, ?DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER},
	 %% {participant_reader, ?DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR},
	 {publications_writer, ?DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER},
	 {publications_reader, ?DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR},
	 {subscriptions_writer, ?DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER},
	 {subscriptions_reader, ?DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR}
	 %% {?DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_ANNOUNCER},
	 %% {?DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_DETECTOR}, 
	 %% {?DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_ANNOUNCER},
	 %% {?DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_DETECTOR},
	 %% {?BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER},
	 %% {?BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER},
	]).

%% LocatorUDPv4
-define(LOCATORUDPv4_INVALID, 0).

-define(PAD, 16#1).
-define(ACKNACK, 16#6).
-define(HEARTBEAT, 16#7).
-define(GAP, 16#8).
-define(INFO_TS, 16#9).
-define(INFO_SRC, 16#c).
-define(INFO_REPLY_IP4, 16#d).
-define(INFO_DST, 16#e).
-define(INFO_REPLY, 16#f).
-define(NACK_FRAG, 16#12).
-define(HEARTBEAT_FRAG, 16#13).
-define(DATA, 16#15).
-define(DATA_FRAG, 16#16).

%% 9.6.2.1 ParticipantMessageData kind
-define(PARTICIPANT_MESSAGE_DATA_KIND_UNKNOWN, <<0, 0, 0, 0>>).
-define(PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE, <<0, 0, 0, 1>>).
-define(PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE, <<0, 0, 0, 2>>).

%% Table 10.1 - Pre-defined data encapsulation schemes
-define(CDR_BE, 0).
-define(CDR_LE, 1).
-define(PL_CDR_BE, 2).
-define(PL_CDR_LE, 3).

-record(header, {protocol_version :: rtps:protocol_version(),
		 vendor_id :: rtps:vendor_id(), guid_prefix :: rtps:guid_prefix()}).

-record(message, {header :: rtps_psm:header(), submessages :: [rtps:submessage()]}).

%% Record used to keep the result of the intermediate result of
%% encoding a submessage. Encoding one of the 'submessage()'s above,
%% results in a tuple containing the id, flags, length and the
%% message's content. This information, particulary the length of the
%% encoded submessage, is used by the rtps_sender while constructing
%% the RTPS messages.
-record(submsg, {id :: ?PAD | ?ACKNACK | ?HEARTBEAT | ?GAP | ?INFO_TS | ?INFO_SRC | 
		       ?INFO_REPLY_IP4 | ?INFO_DST | ?INFO_REPLY | ?NACK_FRAG | 
		       ?HEARTBEAT_FRAG | ?DATA | ?DATA_FRAG,
		 flags :: byte(), length :: 0..16#ffff, content :: binary()}).

-endif.
